#include "FileReader.h"


extern int SIZE_OF_SYMBOL;


FileReader::FileReader(char* szFileName,RD_TYPE eRdType)
{
	m_pFile=fopen(szFileName,"rb");

	switch (eRdType)
	{
	case RD_SRC:
		InitSrcFile();
		break;
	case RD_ZIP:
		InitZipFile();
		break;
	}

	m_iBitSeq=0;
	m_iBitSeqLen=0;
}


FileReader::~FileReader()
{
	fclose(m_pFile);
	delete[] m_aSymbolVector;
	delete[] m_aSymCntVector;
}


void FileReader::GetBit(int* pBit)
{
	if (m_iBitSeqLen==0)
	{
		fread(&m_iBitSeq,1,1,m_pFile);
		m_iBitSeqLen=8;
	}
	*pBit=m_iBitSeq&1;
	m_iBitSeq>>=1;
	m_iBitSeqLen--;
}


void FileReader::GetSymbol(int* pSymbol)
{
	*pSymbol=0;
	fread(pSymbol,SIZE_OF_SYMBOL,1,m_pFile);
}


void FileReader::InitSrcFile()
{
	fseek(m_pFile,0,SEEK_END);
	m_iSymbolsCount=ftell(m_pFile)/SIZE_OF_SYMBOL;
	fseek(m_pFile,0,SEEK_SET);

	int iHistLen=1<<(SIZE_OF_SYMBOL*8);
	int* aHistogram=new int[iHistLen];
	int i;
	for (i=0; i<iHistLen; i++)
		aHistogram[i]=0;

	int iSymbol;
	m_iSymbolsRange=0;
	m_iNumOfSymbols=0;
	for (i=0; i<m_iSymbolsCount; i++)
	{
		GetSymbol(&iSymbol);
		if (m_iSymbolsRange<iSymbol+1)
			m_iSymbolsRange=iSymbol+1;
		if (aHistogram[iSymbol]++==0)
			m_iNumOfSymbols++;
	}
	fseek(m_pFile,0,SEEK_SET);

	int iSymbolNum=0;
	m_aSymbolVector=new int[m_iNumOfSymbols];
	m_aSymCntVector=new int[m_iNumOfSymbols];
	for (i=0; i<m_iSymbolsRange; i++)
	{
		if (aHistogram[i]!=0)
		{
			m_aSymbolVector[iSymbolNum]=i;
			m_aSymCntVector[iSymbolNum]=aHistogram[i];
			iSymbolNum++;
		}
	}

	delete[] aHistogram;
}


void FileReader::InitZipFile()
{
	m_iSymbolsCount=0;
	fread(&m_iSymbolsRange,sizeof(int),1,m_pFile);
	fread(&m_iNumOfSymbols,sizeof(int),1,m_pFile);
	m_aSymbolVector=new int[m_iNumOfSymbols];
	m_aSymCntVector=new int[m_iNumOfSymbols];

	for (int i=0; i<m_iNumOfSymbols; i++)
	{
		GetSymbol(m_aSymbolVector+i);
		fread(m_aSymCntVector+i,sizeof(int),1,m_pFile);
		m_iSymbolsCount+=m_aSymCntVector[i];
	}
}
